#include "head.h"
#include <func.h>

int getCommand(char buf[], char command[]);
int main(int argc, char *argv[]){
    // ./client 192.168.31.128 1234
    ARGS_CHECK(argc, 3);
    int sockFd = socket(AF_INET, SOCK_STREAM, 0);  // 创建一个网络套接字
    struct sockaddr_in addr;
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_family = AF_INET;
    int ret = connect(sockFd, (struct sockaddr*)&addr, sizeof(addr));   // 发起第一次握手
    ERROR_CHECK(ret, -1, "connect");

    puts("select register or login? (1:register; 2:login)");
    char res = getchar();
    send(sockFd, &res, 1, MSG_NOSIGNAL);

    puts("please enter the userName: ");
    char userName[100] = {0};
    char ch;
    int i = 0;
    getchar();
    while((ch = getchar()) != '\n'){
        userName[i++] = ch;
    }
    userName[i] = '\0';

    //发送用户名
    train_t t;
    strcpy(t.buf, userName);
    t.dataLength = strlen(t.buf);
    send(sockFd, &t, sizeof(t.dataLength)+t.dataLength, MSG_NOSIGNAL);

    //查询有无以userName命名的文件，里面装的是token值
    char tokenFile[200] = {0};
    sprintf(tokenFile, "%s%s%s%s%s", ".", "/", PATH, "/", userName);
    // puts(tokenFile);
    int fd = open(tokenFile, O_RDWR|O_CREAT|O_EXCL);
    // printf("fd = %d\n", fd);
    
    char token[100] = {0};
    if(res == '1'){
        /*注册函数：
            1.发送密码
            2.接收token存进文件中*/
        userRegister(sockFd, token, fd);
        // puts(token);
    }else if(res == '2'){
        /* 登录的三种情况：
            1.客户端本地设备保存token信息
            2.客户端本地设备保存token信息但token已过期
            3.客户端本地设备未保存token信息*/
        if(fd == -1){
            //登陆的情况1、2
            //该文件存在，说明已经存在该用户

            //将token发送给服务端
            puts("token in local");
            //send loginInfo   
            send(sockFd, "0", 1, MSG_NOSIGNAL);
            fd = open(tokenFile, O_RDWR|O_CREAT);
            read(fd, token, sizeof(token));
            bzero(&t, sizeof(train_t));
            strcpy(t.buf, token);
            t.dataLength = strlen(t.buf);
            send(sockFd, &t, sizeof(t.dataLength)+t.dataLength, MSG_NOSIGNAL);

            char isRightToken;
            recv(sockFd, &isRightToken, sizeof(isRightToken), MSG_WAITALL);
            if(isRightToken == '0'){
                //token不匹配，情况1、2
                //需要验证用户密码是否正确
                isLegalUser(sockFd, userName);
                char isLegalUser;
                recv(sockFd, &isLegalUser, sizeof(isLegalUser), MSG_WAITALL);
                if(isLegalUser == '0'){
                    //非法用户，关闭
                    close(sockFd);
                    exit(0);
                }
                //合法用户，但token已过期
                //将新的token存入文件中

                //收到token值
                int dataLength;
                recv(sockFd, &dataLength, sizeof(dataLength), MSG_WAITALL);
                recv(sockFd, token, dataLength, MSG_WAITALL);
                
                //存入文件中
                read(fd, token, sizeof(token));
            }
        }else{
            //3.客户端本地设备未保存token信息
            send(sockFd, "1", 1, MSG_NOSIGNAL);
            char password[100] = {0};
            sendUserPassWord(password, sockFd);
            char isLegalUser;
            recv(sockFd, &isLegalUser, sizeof(isLegalUser), MSG_WAITALL);
            if(isLegalUser == '0'){
                //非法用户，关闭
                close(sockFd);
                exit(0);
            }
            
            //收到token值
            int dataLength;
            recv(sockFd, &dataLength, sizeof(dataLength), MSG_WAITALL);
            recv(sockFd, token, dataLength, MSG_WAITALL);
            
            //存入文件中
            read(fd, token, sizeof(token));
        }

    }else{
        close(sockFd);
        exit(0);
    }


    
    // //选择登录还是注册
    // puts("select login or register? (1:login; 2:register)");
    // char res = getchar();
    // //puts(res);
    // send(sockFd, &res, 1, MSG_NOSIGNAL);
    // if(res == '1'){
    //     userLogin(sockFd, argv[3], argv[4]);
    // }else if(res == '2'){
    //     userRegister(sockFd, argv[3], argv[4]);
    // }else{
    //     close(sockFd);
    //     return 0;
    // }
    // getchar();//处理换行符
    
    // char result[1024] = {0};
    // recv(sockFd, result, sizeof(result), 0);
    // puts(result);

    while(1){
        bzero(&t, sizeof(train_t));
        int dataLength;
        char bashPre[1024] = {0};
        char line[1024] = {0};
        char responMsg[1024] = {0};
        // ret = recv(sockFd, buf, sizeof(buf), 0);
        // ERROR_CHECK(ret, -1, "recv xxx$");
        // puts(buf);
        // bzero(buf, sizeof(buf));
        recv(sockFd, &dataLength, sizeof(dataLength), MSG_WAITALL);
        recv(sockFd, bashPre, dataLength, MSG_WAITALL);
        printf("%s ", bashPre);//pwd$
        fflush(stdout);

        rewind(stdin);
        fgets(line, sizeof(line), stdin);
        char commandLine[200] = {0};
        strncpy(commandLine, line, strlen(line)-1);
        // puts(commandLine);
        strcpy(t.buf, commandLine);
        t.dataLength = strlen(t.buf);
        // printf("length = %d, commandLine = %s\n", t.dataLength, t.buf);
        send(sockFd, &t, sizeof(dataLength)+t.dataLength, 0);//发送命令

        char command[1024] = {0};
        getCommand(commandLine, command);
        // printf("%s\n", command);

        if(strcmp(command, "cd") == 0){
            cd(sockFd);
        } 
        else if(strcmp(command, "ls") == 0 ){
            ls(sockFd);
        }
        else if(strcmp(command, "pwd") == 0){
            pwd(sockFd);
        }
        else if(strcmp(command, "rm") == 0){
            removeFile(sockFd);
        }
        else if(strcmp(command, "puts") == 0){
            // puts("if puts");
            upload(commandLine, sockFd);
        }
        else if(strcmp(command, "gets") == 0){
            recvFile(commandLine, sockFd);
        }
        else if(strcmp(command, "mkdir") == 0){
            makedir(sockFd);
        }
        else if(strcmp(command, "rmdir") == 0){
            removedir(sockFd);
        }
        else if(strcmp(command, "exit") == 0){

        }
    }

}


// 根据用户的一整条命令buf 分析出命令的种类，存到command里
int getCommand(char buf[], char command[]){
    for(int i = 0; i < strlen(buf); ++i){
        if(buf[i] == ' ')
            break;
        command[i] = buf[i];
    }
}
